#!/usr/bin/bash
pro_base="$(cd `dirname $(readlink -f $0)`;pwd)"        # program base directory. readlink是为了获取脚本的真实路径
pro_name="$(readlink -f $0 | sed 's#^.*/##; s#.sh$##')" # 删除'/'前的路径,删除'.sh'
stdout_log="${pro_base}/${pro_name}.log"
#export pro_base pro_name

Source(){
    source ${pro_base}/${pro_name}.sh.conf || exit 1
}

Usage()
{
    echo -e "
    /*
     * 说明：
     * 1. ${pro_name} 是指: 用node.js语言写的系统(pbkb: Personal Blog and Knowledge Base)
     * 1.请按需修改 [配置文件]: ${pro_base}/${pro_name}.sh.conf
     * Usage:
     * 执行: bash $0 {-i|-s|-f|-r|-k|-h|--help}
     *                      -i: install依赖包,并配置logrotate
     *                      -s: 后台启动start程序时使用该option(比如在rc.local执行)
     *                      -f: 前台启动进程,启动进程的同时,用tail -f \${stdout_log}查看日志
     *                      -r: 前台 restart 进程,用tail -f \${stdout_log}查看日志
     *                      -k: kill 进程
     */
    "
}                   # $0 总是shell脚本的'路径名/文件名'

Help()              # 若存在 -h 或 --help 选项，则输出 Usage
{
    local i;
    for i
    do
        case $i in
            -h|--help)
                Usage; exit 0;;
            *)
                : ;;
        esac
    done
}

PInfo(){
  echo -e "[ \033[1;33mINFO\033[0m ] `date '+%F %T'` $@"
}

Eval_cont(){
    PInfo "Running: \033[36m$@\033[0m"
    eval "$@"
}

Check_condition(){
    Help "$@"
    [[ $# -ne 1 ]] && Usage && exit 1
}

Process_info(){
    local pid="$(ps -ef |grep "${pro_name}.js"|grep -v grep |awk '{print $2}')"
    if [[ $pid != "" ]]; then
        PInfo "${pro_name}进程已启动,列出进程信息,执行: ps -ef | grep -E 'CMD|${pro_name}.js'"
        ps -ef | grep -E "CMD|${pro_name}.js"
        exit 1
    fi
}

Install_dependence(){
    cd ${pro_base};
    type node || yum install -y nodejs || echo '[Centos7-Ali-epel]
name=Centos7-Ali-epel
baseurl=http://mirrors.aliyun.com/epel/7/$basearch
http://mirrors.aliyuncs.com/epel/7/$basearch
http://mirrors.cloud.aliyuncs.com/epel/7/$basearch
failovermethod=priority
enabled=1
gpgcheck=0' > /etc/yum.repos.d/Centos7-Ali-epel.repo;
    type node || yum install -y nodejs || exit 1
    Eval_cont "npm install express body-parser mariadb cookie-parser multer moment";    # 创建新库/新应用时,第7步,注释此行; 第8步,修改nginx的upstream模块的指向
    touch ${stdout_log};
    PInfo "部署 logrotate..."
    echo "${stdout_log} {
    daily
    rotate 10
    missingok
    notifempty
    su root root
    copytruncate
    compress
}" > /etc/logrotate.d/${pro_name};
}

Start(){
    cd ${pro_base};
    PInfo "${pro_name}.js 进程启动中..."
    node ${pro_base}/${pro_name}.js &>>${stdout_log} &
}
Kill(){
    local pid="$(ps -ef |grep "${pro_name}.js"|grep -v grep |awk '{print $2}')"
    if [[ $pid -gt 1 ]]; then
        PInfo "正在发送 kill -15, 关闭 node 进程与数据库的连接池."
        kill -15 ${pid};                             # node 会优雅地关闭与数据库的连接   # 若下面写作[[ ... -gt 0 ]]就会陷入死循环
        while [[ `mysql -u"${db_user}" -p"${db_password}" -h"${db_host}" -P"${db_port}" -N -e"select count(*) from information_schema.processlist where info is not null and user='${db_user}'"` -gt 1 ]]
        do
            sleep 1
        done
        PInfo "SQL 语句都已经执行完毕,正在发送 kill -9, 关闭 node 进程."
        kill -9 ${pid};
        sleep 0.5;
        [[ $(ps -p ${pid}|wc -l) -eq 1 ]] && PInfo "${pro_name}.js 进程已关闭"
    else
        PInfo "${pro_name}.js 进程不存在"
    fi
    Eval_cont "ps -ef |grep '${pro_name}.js'"
}

case $1 in
    -s)
        {
        Source
        Check_condition "$@"
        Process_info
        Start
        } &>> ${stdout_log}                     # 在后台运行,不在 屏幕产生 stdout 或 stderr
    ;;
    -f)
        Source
        Check_condition "$@"
        touch ${stdout_log}                     # 避免下面的 tail 先于 Start 执行时,若不存在${stdout_log}会出错
        log_size=$(wc -c ${stdout_log}|awk '{print $1}')
        Process_info
        Start
        Eval_cont "tail -f -c +${log_size} ${stdout_log}"
    ;;
    -i)
        Source
        Check_condition "$@"
        Install_dependence
    ;;
    -k)
        Source
        Check_condition "$@"
        Kill
    ;;
    -r)
        Source
        Check_condition "$@"
        Kill
        touch ${stdout_log}
        log_size=$(wc -c ${stdout_log}|awk '{print $1}')
        Start
        Eval_cont "tail -f -c +${log_size} ${stdout_log}"
    ;;
    *)
        Source
        Usage && exit 1
    ;;
esac
